#include <algorithm>
#include <iostream>
using namespace std;
struct f{
	int rank,sum;
}cou[10];
typedef struct f f;
bool cmp(f a,f b){
	return a.sum<b.sum;
}
int a[10][10]/*分数数组*/,b[10][10]/*数独数组*/,s[100][4]/*空位的数组0:行1:列2:分值3:宫*/,u=0/*第几个空位*/;
bool hang[10][10]/*第i行有没有n*/,lie[10][10]/*第j列有没有n*/,gong[10][10]/*第k宫有没有n*/;
int score=0/*初始分值*/,most=-1/*最终分值*/;

void init();/*初始化分数数组，并将cou数组的rank值赋值为i*/
int which(int i,int j);/*判断该坐标是在哪个宫*/
void dfs(int n/*第n个空位*/,int fen/*实时分值*/);
int main(){
	int i,j;
	init();
	for(i = 1;i<10;++i)
		for(j = 1;j<10;++j){
			cin>>b[i][j];
			if(b[i][j]){
				hang[i][b[i][j]]=lie[j][b[i][j]]=gong[which(i,j)][b[i][j]]=true;/*第i行，第j列，第which宫都包含b[i][j]这个数啦！*/
				score+=b[i][j]*a[i][j];/*算一下已经填出的数字的分值和*/ 
			}
			else cou[i].sum++;/*如果是0，就让这行的0的个数加1*/
		}
	sort(cou+1,cou+10,cmp);/*按照cmp规则，将0少的行排在前面，同时因为rank之前赋值了i，可以很轻松的知道原来是第几行*/
	for(i=1;i<10;++i){
		for(j=1;j<10;++j){
			if(b[cou[i].rank][j]==0){/*注意，这里cou[i]是从0少的行开始的，而rank正好求出原来是第几行，所以.rank不能丢*/
				s[u][0]=cou[i].rank;/*存储第u(初值为0)个空位的行(0)列(1)分值(2)宫(3)，之后u++*/
				s[u][1]=j;
				s[u][2]=a[cou[i].rank][j];
				s[u++][3]=which(cou[i].rank,j);
			}
		}
	}
	dfs(0,score);
	cout<<most; /*most初值为-1*/
	return 0;
}
void init(){
	int i,j,k;
	for(i = 1;i<6;++i)
		for(j = i;j<11-i;++j)
			for(k = i;k<11-i;++k)
				a[j][k] = 5+i;
	for(i=1;i<10;++i)
		cou[i].rank=i;
}
void dfs(int n/*第n个空位*/,int fen/*实时分值*/){
	if(n==u){
		most=max(most,fen);/*如果所有空位都能填满，用max求得最大分值。*/
		return;
	}
	for(int i=1;i<10;++i){
		if(!hang[s[n][0]][i]&&!lie[s[n][1]][i]&&!gong[s[n][3]][i]){/*在填第n个空位的时候，如果s[n][0]行，s[n][1]列，s[n][3]宫都没填过i*/ 
			hang[s[n][0]][i]=lie[s[n][1]][i]=gong[s[n][3]][i]=true;/*将i填进去*/
			dfs(n+1,fen+s[n][2]*i);/*递归下一个空位*/
			hang[s[n][0]][i]=lie[s[n][1]][i]=gong[s[n][3]][i]=false;/*回溯*/
		}
	}
}
int which(int i,int j){
	if(i<4&&j<4)return 1;
	if(i<4&&j>3&&j<7)return 2;
	if(i<4&&j>6)return 3;
	if(i>3&&i<7&&j<4)return 4;
	if(i>3&&i<7&&j>3&&j<7)return 5;
	if(i>3&&i<7&&j>6)return 6;
	if(i>6&&j<4)return 7;
	if(i>6&&j>3&&j<7)return 8;
	if(i>6&&j>6)return 9;

}